package com.decade.qiyeshapan.service;

import com.decade.qiyeshapan.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.context.annotation.Lazy;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.decade.qiyeshapan.config.RedisKeyManager;

import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.List;

@Service
public class UserService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    private HashOperations<String, String, User> hashOperations;
    
    @Autowired
    @Lazy
    private MessageService messageService;
    @Autowired
    private GameService gameService;

    @PostConstruct
    private void init() {
        hashOperations = redisTemplate.opsForHash();
    }

    public void saveUser(User user) {
        String key = RedisKeyManager.userHash(user.getGameId());
        String roomInfoKey = RedisKeyManager.gameInfo(user.getGameId());
        
        if (!redisTemplate.hasKey(roomInfoKey)) {
            HashOperations<String, Object, Object> roomHashOps = redisTemplate.opsForHash();
            roomHashOps.put(roomInfoKey, "createdAt", System.currentTimeMillis());
            roomHashOps.put(roomInfoKey, "players", JSONUtil.createArray().toString());
            roomHashOps.put(roomInfoKey, "status", "waiting");
            System.out.println("自动创建新房间: " + user.getGameId());
        }
        
        if (hashOperations.hasKey(key, user.getUsername())) {
            throw new IllegalArgumentException("用户名已存在");
        }
        
        user.setUserId(UUID.randomUUID().toString());
        hashOperations.put(key, user.getUsername(), user);
        gameService.addPlayerToGame(user.getGameId(), user.getUsername());
    }

    public User getUser(String gameId, String username) {
        return hashOperations.get("game:" + gameId, username);
    }

    public void deleteUser(String gameId, String username) {
        hashOperations.delete("game:" + gameId, username);
    }

    public Map<String, User> getAllUsers(String gameId) {
        String key = "game:" + gameId;
        return hashOperations.entries(key)
            .entrySet()
            .stream()
            .filter(entry -> entry.getValue() instanceof User)
            .collect(Collectors.toMap(
                Map.Entry::getKey,
                entry -> (User) entry.getValue()
            ));
    }

    public void updateProgress(String gameId, String username, int progress) {
        String key = "game:" + gameId;
        User user = hashOperations.get(key, username);
        if (user == null) {
            throw new IllegalArgumentException("User not found");
        }
        user.setCurrentProgress(progress);
        hashOperations.put(key, username, user);
    }

    public void updateSocketId(String gameId, String username, String socketId) {
        String key = "game:" + gameId;
        User user = hashOperations.get(key, username);
        if (user == null) {
            throw new IllegalArgumentException("User not found");
        }
        user.setSocketId(socketId);
        hashOperations.put(key, username, user);
    }

    public void toggleReady(String gameId, String username, boolean isReady) {
        String key = "game:" + gameId;
        redisTemplate.execute(new SessionCallback<>() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                operations.watch(key);
                User user = hashOperations.get(key, username);
                if (user == null) {
                    throw new IllegalArgumentException("用户不存在");
                }
                user.setReady(isReady);
                operations.multi();
                operations.opsForHash().put(key, username, user);

                //用户准备状态变更之后，通知页面刷新用户状态
                messageService.broadcastPlayerStatus(gameId);
                return operations.exec();
            }
        });
    }

    public void startGame(String gameId) {
        String roomInfoKey = "game:" + gameId + ":info";
        HashOperations<String, Object, Object> hashOps = redisTemplate.opsForHash();
        hashOps.put(roomInfoKey, "status", "running");
        hashOps.put(roomInfoKey, "currentYear", 1);
        hashOps.put(roomInfoKey, "currentQuarter", 1);
    }

    public JSONObject getGameInfo(String gameId) {
        String roomInfoKey = "game:" + gameId + ":info";
        HashOperations<String, Object, Object> hashOps = redisTemplate.opsForHash();
        Map<Object, Object> entries = hashOps.entries(roomInfoKey);
        return JSONUtil.parseObj(entries);
    }

    public void updateGameInfo(String gameId, JSONObject gameInfo) {
        String roomInfoKey = "game:" + gameId + ":info";
        HashOperations<String, Object, Object> hashOps = redisTemplate.opsForHash();
        gameInfo.forEach((key, value) -> hashOps.put(roomInfoKey, key, value));
    }

    public void updateTaskProgress(String gameId, String username, int progress) {
        String key = "game:" + gameId;
        User user = hashOperations.get(key, username);
        if (user == null) {
            throw new IllegalArgumentException("用户不存在");
        }
        user.setTaskProgress(progress);
        hashOperations.put(key, username, user);
        
        // 广播进度更新
        JSONObject msg = JSONUtil.createObj()
            .set("type", "progressUpdate")
            .set("username", username)
            .set("progress", progress);
        messageService.broadcastToGame(gameId, msg.toString());
    }

    public void saveAdvertisement(String gameId, String username, String region, String product, int amount) {
        String zsetKey = RedisKeyManager.adRanking(gameId, region, product);
        redisTemplate.opsForZSet().add(zsetKey, username, amount);
        
        // 更新用户总投入（可选）
        String userTotalKey = RedisKeyManager.userAdTotal(gameId, username);
        redisTemplate.opsForZSet().incrementScore(userTotalKey, product, amount);
    }

    public void batchSaveAdvertisements(String gameId, String username, List<Map<String, Object>> ads) {
        // 使用管道批量操作
        redisTemplate.executePipelined(new SessionCallback<Object>() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                for (Map<String, Object> ad : ads) {
                    String region = ad.get("region").toString();
                    String product = ad.get("product").toString();
                    int amount = Integer.parseInt(ad.get("amount").toString());

                    // 按区域+产品存储
                    String zsetKey = RedisKeyManager.adRanking(gameId, region, product);
                    operations.opsForZSet().add(zsetKey, username, amount);

                    // 更新用户总投入
                    String userTotalKey = RedisKeyManager.userAdTotal(gameId, username);
                    operations.opsForZSet().incrementScore(userTotalKey, product, amount);
                }
                return null;
            }
        });
    }
} 